package com.aloda.aop;

import com.aloda.mapper.LogMapper;
import com.aloda.pojo.dto.*;
import com.aloda.pojo.entity.Log;
import com.aloda.result.Result;
import com.aloda.utils.UserHolder;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;

import java.time.LocalDateTime;
import java.util.Arrays;

/**
 * 操作日志切面
 */
@Aspect
public class OpLogAspect {

    @Autowired
    private LogMapper logMapper;

    /**
     * 记录操作日志
     *
     * @param joinPoint
     * @return
     * @throws Throwable
     */
    @Around("@annotation(com.aloda.anno.OperationLog)")
    public Object operationLog(ProceedingJoinPoint joinPoint) throws Throwable {
        // 获取操作者信息
        UserSafetyDTO user = UserHolder.getUser();
        // 获取操作时间
        LocalDateTime operateTime = LocalDateTime.now();
        // 获取操作类名
        String className = joinPoint.getTarget().getClass().getName();
        String shortClassName = className.substring(className.lastIndexOf(".") + 1);
        // 获取操作的方法名
        String methodName = joinPoint.getSignature().getName();
        // 操作方法的参数
        Object[] args = joinPoint.getArgs();
        String methodParams = Arrays.toString(args);

        long begin = System.currentTimeMillis();

        // 调用原始目标方法运行
        Object result = joinPoint.proceed();

        long end = System.currentTimeMillis();
        // 操作耗时
        long costTime = end - begin;

        // 方法返回值
        String returnValue = result.toString();
        // 记录操作结果状态
        Integer resultStatus = null;
        if (result instanceof Result) {
            Result res = (Result) result;
            resultStatus = res.getCode();
        }

        Log log = new Log();
        log.setUserId(user.getId());
        log.setUsername(user.getName());
        log.setCostTime(costTime);
        log.setOperateTime(operateTime.toString());
        log.setClassName(shortClassName);
        log.setMethodName(methodName);
        log.setMethodParams(methodParams);
        log.setReturnValue(returnValue);
        log.setResultStatus(resultStatus);

        // 记录操作类型与详细参数
        // 新增用户
        if (args[0] instanceof UserAddDTO) {
            String operateDesc = "新增用户操作";
            log.setOperateDesc(operateDesc);
            UserAddDTO userAddDTO = (UserAddDTO) args[0];
            String operateParams = "名称：" + userAddDTO.getName() + " "
                    + "邮箱："+ userAddDTO.getEmail() + " "
                    + "用户角色："+ userAddDTO.getRole() + " "
                    + "用户密码："+ userAddDTO.getPassword();
            log.setOperateParams(operateParams);
        }else if (args[0] instanceof UserEditDTO) {
            String operateDesc = "编辑用户操作";
            log.setOperateDesc(operateDesc);
            UserEditDTO userEditDTO = (UserEditDTO) args[0];
            String operateParams = "用户id" + userEditDTO.getId().toString() + " "
                    + "名称：" + userEditDTO.getName() + " "
                    + "邮箱："+ userEditDTO.getEmail() + " "
                    + "用户角色："+ userEditDTO.getRole();
            log.setOperateParams(operateParams);
        }else if (args[0] instanceof BookAddDTO) {
            String operateDesc = "新增图书操作";
            log.setOperateDesc(operateDesc);
            String operateParams = "暂无参数详细记录，请查看日志基础格式";
            log.setOperateParams(operateParams);
        }else if (args[0] instanceof BookEditDTO) {
            String operateDesc = "编辑图书操作";
            log.setOperateDesc(operateDesc);
            String operateParams = "暂无参数详细记录，请查看日志基础格式";
            log.setOperateParams(operateParams);
        }else {
            String operateDesc = "暂无日志描述";
            log.setOperateDesc(operateDesc);
            String operateParams = "暂无参数详细记录，请查看日志基础格式";
            log.setOperateParams(operateParams);
        }

        // 新增日志
        logMapper.insert(log);
        return result;
    }
}
